﻿using Hx.ADSyncPlatform.ActiveDirectory;
using Hx.ADSyncPlatform.ActiveDirectory.Extension;
using Hx.ADSyncPlatform.ActiveDirectory.Model;
using Hx.ADSyncPlatform.Common.ExportExcel;
using Hx.ADSyncPlatform.Controllers.Base;
using Hx.ADSyncPlatform.Entity.Models;
using Hx.ADSyncPlatform.Infrastructure.Page;
using Hx.ADSyncPlatform.Service;
using Hx.ADSyncPlatform.WebApi.Model;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Threading.Tasks;

namespace Hx.ADSyncPlatform.Controllers
{
    /// <summary>
    /// 机构控制器
    /// </summary>
    [Route("api/ad/organization")]
    [Authorize]
    [ApiController]
    public class OrganizationController : BaseController
    {
        private ActiveDirectoryClient activeDirectoryClient;

        private SystemConfig systemConfig;

        private Plat_DataPermissionService plat_DataPermissionService;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="serviceProvider"></param>
        /// <param name="activeDirectoryClient"></param>
        public OrganizationController(IOptions<SystemConfig> myOptionsAccessor,
            IServiceProvider serviceProvider
            , ActiveDirectoryClient activeDirectoryClient, Plat_DataPermissionService plat_DataPermissionService) : base(serviceProvider)
        {
            this.activeDirectoryClient = activeDirectoryClient;
            this.systemConfig = myOptionsAccessor.Value;
            this.plat_DataPermissionService = plat_DataPermissionService;
            activeDirectoryClient.Organizations.filterOrgByDataPermission = plat_DataPermissionService.FilterOrgHandler;
        }




        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        [HttpGet("root")]
        public async Task<Result<Organization>> Root()
        {
            Organization organization = activeDirectoryClient.Organizations.Root();
            return await base.Success<Organization>(organization);

        }


        /// 
        /// </summary>
        /// <returns></returns>
        [HttpGet("tree")]
        public async Task<Result<List<OuTreeModel>>> Tree()
        {
            Organization organization = activeDirectoryClient.Organizations.Root();
            OuTreeModel treeModel = organization.ConvertToTree();
            List<string> excludeCnList = systemConfig.systemOU.Select(n => n.cn).ToList();
            List<Organization> organizations = activeDirectoryClient.Organizations.GetByDN(organization.DistinguishedName, SearchScopeDerivation.OneLevel, excludeCnList);

            List<OuTreeModel> subList = organizations.ConvertToTree();
            subList.ForEach(n =>
            {
                n.isLeaf = !activeDirectoryClient.Organizations.HasChildren(n.data.DistinguishedName, excludeCnList, platManager.DataPermissions);
            });
            treeModel.children = subList;
            return await base.Success<List<OuTreeModel>>(new List<OuTreeModel>() { treeModel });

        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="cn"></param>
        /// <returns></returns>
        [HttpGet("sublist")]
        public async Task<Result<List<OuTreeModel>>> SubList(string dn)
        {
            List<string> excludeCnList = systemConfig.systemOU.Select(n => n.cn).ToList();
            List<Organization> organizations = activeDirectoryClient.Organizations.GetByDN(dn, SearchScopeDerivation.OneLevel, excludeCnList);
            organizations = await this.plat_DataPermissionService.FilterOrg(platManager.ManagerId, organizations);

            List<OuTreeModel> subList = organizations.ConvertToTree();
            subList.ForEach(n =>
            {
                n.isLeaf = !activeDirectoryClient.Organizations.HasChildren(n.data.DistinguishedName, excludeCnList, platManager.DataPermissions);
            });
            return await base.Success<List<OuTreeModel>>(subList);

        }

        /// <summary>
        /// 分页
        /// </summary>
        /// <param name="cn"></param>
        /// <returns></returns>
        [HttpGet("subPageList")]
        public async Task<Result<PageResult<Organization>>> SubPageList(string parentCn, string displayName, string searchScope, [FromQuery] Pagination pagination)
        {

            PageResult<Organization> organizations = activeDirectoryClient.Organizations.PageList(parentCn, displayName, platManager.DataPermissions, searchScope, pagination.pageNum, pagination.pageSize);

            return await base.Success<PageResult<Organization>>(organizations);

        }
        /// <summary>
        /// 导出Excel
        /// </summary>
        [HttpPost("exportExcel")]
        public async Task<object> ExportOrganizationExcel(string parentCn, string displayName, string searchScope)
        {
            try
            {
                List<Organization> organizations = activeDirectoryClient.Organizations.Get(parentCn, displayName, platManager.DataPermissions, searchScope);
                if (!organizations.Any()) return await base.Fail("导出失败！");
                List<ExportOrganizationModel> OrganizationModelData = mapper.Map<List<ExportOrganizationModel>>(organizations);
                TimeSpan ts = DateTime.Now - new DateTime(1970, 1, 1, 0, 0, 0, 0);
                string excelName = $"Organization{Convert.ToInt64(ts.TotalSeconds)}.xlsx";
                List<(string, List<object>)> tuples =
                new List<(string, List<object>)>();
                tuples.Add(("组织", OrganizationModelData.Select(d => (object)d).ToList()));
                //tuples.Add(("人员", lepm.Select(d => (object)d).ToList()));
                var stream = ExcelHelper.ExportExcels(tuples);
                if (stream != null)
                {
                    return File(stream.ToArray(), "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", excelName);
                }

                return await base.Fail("导出失败！");
            }
            catch (Exception ex)
            {
                return await base.Fail(ex.Message);
            }
        }
    }
}
